package com.alphasystem.commerce.common.model.sequence;

import static java.lang.String.format;
import static javax.persistence.InheritanceType.JOINED;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import com.alphasystem.commerce.common.util.HashCodeUtil;

/**
 * @author Syed F Ali
 */
@Entity
@Table(name = "SEQ_GEN")
@Inheritance(strategy = JOINED)
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "SequenceType", propOrder = { "name", "initial", "blockSize",
		"prefix", "suffix" })
public class Sequence implements Serializable, Comparable<Sequence> {

	private static final long serialVersionUID = 3039368170170933550L;

	protected long blockSize;

	protected long initial;

	protected String name;

	protected String prefix;

	protected String suffix;

	protected long last;

	public Sequence() {
	}

	public Sequence(String name, long initial, long blockSize, String prefix,
			String suffix) {
		this.blockSize = blockSize;
		this.initial = initial;
		this.name = name;
		this.prefix = prefix;
		this.suffix = suffix;
		this.last = -1L;
	}

	public Sequence(String name, Sequence src) {
		this(name, src.getInitial(), src.getBlockSize(), src.getPrefix(), src
				.getSuffix());
	}

	public int compareTo(Sequence o) {
		return o.getName().compareTo(name);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Sequence) {
			Sequence o = (Sequence) obj;
			return o.getName().equals(name);
		}
		return false;
	}

	/**
	 * @return the blockSize
	 */
	@Column(name = "BLOCK_SIZE")
	@XmlElement(name = "block-size")
	public long getBlockSize() {
		return blockSize;
	}

	/**
	 * @return the initial
	 */
	@Column(name = "INITIAL_VALUE")
	public long getInitial() {
		return initial;
	}

	/**
	 * @return the last
	 */
	@Transient
	@XmlTransient
	public long getLast() {
		return last;
	}

	/**
	 * @return the name
	 */
	@Id
	@Column(length = 40)
	@XmlElement(required = true)
	public String getName() {
		return name;
	}

	/**
	 * @return the prefix
	 */
	@Column(length = 10)
	public String getPrefix() {
		return prefix;
	}

	/**
	 * @return the suffix
	 */
	@Column(length = 10)
	public String getSuffix() {
		return suffix;
	}

	@Override
	public int hashCode() {
		return HashCodeUtil.hash(name);
	}

	public void increment() {
		long temp = initial;
		initial += blockSize;
		last = temp;
	}

	/**
	 * @param blockSize
	 *            the blockSize to set
	 */
	public void setBlockSize(long blockSize) {
		this.blockSize = blockSize;
	}

	/**
	 * @param initial
	 *            the initial to set
	 */
	public void setInitial(long initial) {
		this.initial = initial;
	}

	/**
	 * @param last
	 *            the last to set
	 */
	public void setLast(long last) {
		this.last = last;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @param prefix
	 *            the prefix to set
	 */
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	/**
	 * @param suffix
	 *            the suffix to set
	 */
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}

	@Override
	public String toString() {
		String s = format(
				"%s:- Name: %s, Initial: %s, Block Size: %s, Last: %s, Prefix: %s, Suffix: %s",
				getClass().getSimpleName(), name, initial, blockSize, last,
				prefix, suffix);
		return s;
	}
}
